
package com.rt.schedulenew.service.impl;

import com.alibaba.druid.support.json.JSONUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.rt.schedulebase.core.websocket.NettyPushServer;
import com.rt.schedulebase.dto.DeptNoticeDto;
import com.rt.schedulebase.dto.DictUsersDto;
import com.rt.schedulebase.entity.DeptMailbox;
import com.rt.schedulebase.entity.DeptNotice;
import com.rt.schedulebase.entity.commonentity.PageResultUtil;
import com.rt.schedulebase.mapper.DeptNoticeMapper;
import com.rt.schedulenew.api.IDeptMailboxService;
import com.rt.schedulenew.api.IDeptNoticeService;
import com.rt.schedulenew.api.IDictUsersService;
import com.rt.schedulenew.utils.base.ConstantsUtil;
import com.rt.schedulenew.utils.global.CustomMessage;
import com.rt.schedulenew.utils.global.ErrorCode;
import com.rt.schedulenew.utils.global.JsonResult;
import com.rt.schedulenew.utils.global.JsonResultUtil;
import com.rt.schedulenew.utils.pkgenerator.PKGeneratorSingle;
import com.rt.schedulenew.utils.util.DateUtil;
import com.rt.schedulenew.utils.util.JsonUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class DeptNoticeServiceImpl extends ServiceImpl<DeptNoticeMapper, DeptNotice> implements IDeptNoticeService {
    @Autowired
    private IDictUsersService dictUsersService;
    @Autowired
    private IDeptMailboxService deptMailboxService;
    @Autowired
    private NettyPushServer nettyPushServer;

    @Override
    public boolean insertSelective(DeptNotice deptNotice) {
        return retBool(baseMapper.insert(deptNotice));
    }

    @Override
    public boolean deleteByPrimaryKey(String key) {
        return retBool(baseMapper.deleteById(key));
    }

    @Override
    public boolean updateByPrimaryKeySelective(DeptNotice deptNotice) {
        return retBool(baseMapper.updateById(deptNotice));
    }

    @Override
    public DeptNotice selectByPrimaryKey(String key) {
        return baseMapper.selectById(key);
    }

    @Override
    public List<DeptNotice> getList(DeptNoticeDto dto) {
        Map<String, Object> map = new HashMap<String, Object>();
        QueryWrapper<DeptNotice> qw = new QueryWrapper<>();
        map.put("DEPT_CODE", dto.getDeptCode());
        map.put("NOTICE_TYPE", dto.getNoticeType());
        map.put("EXAM_NO", dto.getExamNo());
        qw.allEq(map, false);
        List<DeptNotice> list = baseMapper.selectList(qw);
        return list;
    }

    @Override
    public List<DeptNotice> getListAll() {
        return baseMapper.selectList(null);
    }

    @Override
    public boolean delete(DeptNotice deptNotice) {
        Map<String, Object> map = new HashMap<String, Object>();
        UpdateWrapper<DeptNotice> uw = new UpdateWrapper<>();
        map.put("NOTICE_ID", deptNotice.getNoticeId());
        map.put("EXAM_NO", deptNotice.getExamNo());
        map.put("NOTICE_TYPE", deptNotice.getNoticeType());
        uw.allEq(map, false);
        return retBool(baseMapper.delete(uw));
    }

    @Override
    public boolean update(DeptNotice deptNotice) {
        Map<String, Object> map = new HashMap<>();
        UpdateWrapper<DeptNotice> uw = new UpdateWrapper<>();
        map.put("NOTICE_ID", deptNotice.getNoticeId());
        map.put("EXAM_NO", deptNotice.getExamNo());
        map.put("NOTICE_TYPE", deptNotice.getNoticeType());

        uw.allEq(map, false);
        return retBool(baseMapper.update(deptNotice, uw));
    }

    @Override
    public DeptNotice getInfo(DeptNoticeDto dto) {
        Map<String, Object> map = new HashMap<>();
        QueryWrapper<DeptNotice> qw = new QueryWrapper<>();
        map.put("NOTICE_ID", dto.getNoticeId());
        map.put("EXAM_NO", dto.getExamNo());
        qw.allEq(map, false);
        return baseMapper.selectOne(qw);
    }

    /**
     * 推送部门消息
     * @author ljy
     * @param deptNoticeDto 消息对象和内容
     * @param userDto 操作者信息
     * @return  返回操作结果
     */
    @Override
    public JsonResult saveDeptNotice(DeptNoticeDto deptNoticeDto, DictUsersDto userDto) {
        DeptNotice deptNotice = new DeptNotice();
        deptNotice.setValidityDate("");
        deptNotice.setValidityTime("");
        deptNotice.setSendOwner(userDto.getName());
        deptNotice.setDeptCode(deptNoticeDto.getReqDept());
        deptNotice.setExamNo(deptNoticeDto.getApplyNo());
        deptNotice.setSendDate(DateUtil.getCurrDateStr());
        deptNotice.setNoticeId(PKGeneratorSingle.getInstance().nextPKStr());
        deptNotice.setSendTime(DateUtil.formatCurrentTime(DateUtil.FORMAT_TIME));
        String content = "";
        if (Objects.equals(deptNoticeDto.getActType(), ConstantsUtil.ActType.UPDATE.getType())) {
            content = "修改预约：" + deptNoticeDto.getOldScheduleDate() + " " + deptNoticeDto.getOldScheduleApm() + "，改约到" + deptNoticeDto.getScheduledDate() + " " + deptNoticeDto.getScheduleApm();
            deptNotice.setNoticeType(ConstantsUtil.NoticeType.CANCEL.getType());
        } else if (Objects.equals(deptNoticeDto.getActType(), ConstantsUtil.ActType.CANCEL.getType())) {
            content = "取消预约：" + deptNoticeDto.getScheduledDate() + " " + deptNoticeDto.getScheduleApm() + "预约已取消";
            deptNotice.setNoticeType(ConstantsUtil.NoticeType.UPDATE.getType());
        } else if (Objects.equals(deptNoticeDto.getActType(), ConstantsUtil.ActType.CONFIRM.getType())) {
            content = "预约完成：" + deptNoticeDto.getScheduledDate() + " " + deptNoticeDto.getScheduleApm() + "预约成功";
            deptNotice.setNoticeType(ConstantsUtil.NoticeType.CONFIRM.getType());
        }
        Map<String, String> map = new HashMap<>();
        map.put("deptName", deptNoticeDto.getDeptName());
        map.put("sex", deptNoticeDto.getSex());
        map.put("age", deptNoticeDto.getAge());
        map.put("name", deptNoticeDto.getName());
        map.put("actType", deptNoticeDto.getActType());
        map.put("scheduledDate", deptNoticeDto.getScheduledDate());
        map.put("scheduleApm", deptNoticeDto.getScheduleApm());
        map.put("oldScheduleDate", deptNoticeDto.getOldScheduleDate());
        map.put("oldScheduleApm", deptNoticeDto.getOldScheduleApm());
        map.put("itemName", deptNoticeDto.getItemName());
        map.put("scheduler", userDto.getName());
        map.put("applyNo", String.join(";", deptNoticeDto.getApplyNos()));
        deptNotice.setSendContent(JSONUtils.toJSONString(map));
        DeptNoticeDto noticeDto = new DeptNoticeDto();
        noticeDto.setExamNo(deptNoticeDto.getApplyNo());
        DeptNotice deptNotice2 = getInfo(noticeDto);
        if (delete(noticeDto)) {
            deptMailboxService.deleteByPrimaryKey(deptNotice2.getNoticeId());
        }
        if (insertSelective(deptNotice) && StringUtils.isNotBlank(deptNoticeDto.getReqWardCode())) {
            DictUsersDto userSelect = new DictUsersDto();
            userSelect.setWardCode(deptNoticeDto.getReqWardCode());
            List<DictUsersDto> userList = dictUsersService.getUserList(userSelect);
            userList = userList.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> (new TreeSet<>(Comparator.comparing(e -> (e.getUserId() != null ? e.getUserId() : ""))))), ArrayList::new));
            for (DictUsersDto dictUsers : userList) {
                if (StringUtils.isBlank(dictUsers.getUserId())) {
                    continue;
                }
                DeptMailbox deptMailbox = new DeptMailbox();
                deptMailbox.setNoticeId(deptNotice.getNoticeId());
                deptMailbox.setUserId(dictUsers.getUserId());
                deptMailboxService.insertSelective(deptMailbox);
                CustomMessage customMessage = new CustomMessage();
                int unreadCount = deptMailboxService.unreadCount(deptMailbox);
                customMessage.setType(ConstantsUtil.NettyMsgCode.YY_ONE.getCode());
                customMessage.setContent(JsonResultUtil.success(ErrorCode.SUCCESS.getValue(), unreadCount));

                // 推送消息
                nettyPushServer.sendMessageToUser(dictUsers.getUserId(), JsonUtil.toJson(customMessage));
                String msg = "患者:" + deptNoticeDto.getName() + "," + deptNoticeDto.getExamClass() + "检查," + content;
                customMessage.setType(ConstantsUtil.NettyMsgCode.YY_TOW.getCode());
                customMessage.setContent(JsonResultUtil.success(ErrorCode.SUCCESS.getValue(), msg));
                // // 推送消息
                nettyPushServer.sendMessageToUser(dictUsers.getUserId(), JsonUtil.toJson(customMessage));
            }
        }
        return JsonResultUtil.success("操作成功");
    }

    @Override
    public JsonResult getDeptNoticeList(DeptNoticeDto dto) {
        Page<DeptNoticeDto> page = new Page<>();
        if (dto.getPageNo() != null && dto.getPageSize() != null) {
            page = PageHelper.startPage(dto.getPageNo(), dto.getPageSize());
        }
        List<DeptNoticeDto> list = baseMapper.getDeptNoticeList(dto);
        for (DeptNoticeDto noticeDto : list) {
            noticeDto.setJsonContent(JsonUtil.json2Map(noticeDto.getSendContent()));
        }
        return PageResultUtil.success(ErrorCode.SUCCESS.getValue(), list, page);
    }
}
